import envConfig from '../env'
import common from "../common/index";
import constants from "../common/constants";
import {ChatItemType, ChatStatusEnum, ResDto} from '../types/index';
const TextEncoding = require('text-encoding-shim');

const request = (options: {
    url: string, method?:
        | 'OPTIONS'
        | 'GET'
        | 'HEAD'
        | 'POST'
        | 'PUT'
        | 'DELETE'
        | 'TRACE'
        | 'CONNECT', header?: Object | undefined, timeout?: number, data: any, dataType?: 'json' | '其他', responseType?: 'text' | 'arraybuffer'
}): Promise<ResDto> => {
    return new Promise((resolve, reject) => {
        options.header = options.header || {}
        const token: string = common.getLocalToken()
        const headers: any = options.header || {}
        headers[constants.ApiHeaderTokenKey] = 'Bearer ' + token
        
        const fullUrl = envConfig.apiBase + options.url
        console.log(`[Request] ${options.method || 'GET'} ${fullUrl}`)
        console.log('[Request] Headers:', headers)
        console.log('[Request] Data:', options.data)
        
        wx.request({
            url: fullUrl,
            method: options.method,
            header: headers,
            timeout: options.timeout || 60000,
            data: options.data,
            dataType: options.dataType || 'json',
            responseType: options.responseType || 'text',
            success: (res) => {
                console.log(`[Request Success] ${fullUrl}`, res.statusCode, res.data)
                // 检查HTTP状态码
                if (res.statusCode >= 200 && res.statusCode < 300) {
                    resolve(res.data)
                } else {
                    console.error(`[Request Error] HTTP ${res.statusCode}:`, res.data)
                    const errorMsg = `请求失败: HTTP ${res.statusCode}`
                    reject({
                        code: res.statusCode,
                        msg: errorMsg,
                        data: res.data
                    })
                }
            },
            fail: (err) => {
                console.error(`[Request Fail] ${fullUrl}:`, err)
                // 详细错误信息
                let errorMsg = '网络请求失败'
                if (err.errMsg) {
                    if (err.errMsg.includes('request:fail')) {
                        if (err.errMsg.includes('域名不在以下 request 合法域名列表中')) {
                            errorMsg = '请求域名未配置，请在微信小程序后台配置request合法域名'
                        } else if (err.errMsg.includes('timeout')) {
                            errorMsg = '请求超时，请检查网络连接'
                        } else if (err.errMsg.includes('SSL')) {
                            errorMsg = 'SSL证书验证失败'
                        } else {
                            errorMsg = `网络错误: ${err.errMsg}`
                        }
                    } else {
                        errorMsg = err.errMsg
                    }
                }
                reject({
                    code: -1,
                    msg: errorMsg,
                    errMsg: err.errMsg,
                    err: err
                })
            }
        })
    })

}
const post = (url: string, data: any): Promise<ResDto> => {
    return request({
        url,
        method: 'POST',
        header: {
            'Content-Type': 'application/json'
        },
        data,
    })
}
const get = (url: string, data: any): Promise<ResDto> => {
    return request({
        url,
        method: 'GET',
        header: {
            'Content-Type': 'application/json'
        },
        data,
    })
}
const stream = (url: string, data: any, chatItem: ChatItemType, {reasonCall, answerCall, errorCall, completeCall}: {reasonCall?: Function, answerCall?: Function, errorCall?: Function,  completeCall?: Function}) => {
    const handleComplete = () => {
        requestTask.abort()
        chatItem.status = ChatStatusEnum.Stop
        chatItem.loading = false
        chatItem.reasoningFinish = true
        chatItem.finish = true
        completeCall && completeCall()
    }
    chatItem.loading = true
    chatItem.reasoningFinish = false
    chatItem.finish = false
    chatItem.aispire = ''
    chatItem.reasoning = ''
    chatItem.status = ChatStatusEnum.Start
    const token: string = common.getLocalToken()
    const headers: any =  {}
    headers[constants.ApiHeaderTokenKey] = 'Bearer ' + token
    let buffer = new Uint8Array(0)
    const requestTask = wx.request({
        url: envConfig.apiBase + url,
        method: 'POST',
        header: headers,
        timeout: 3600000,
        data: JSON.stringify(data || {}),
        enableChunked: true,
        responseType: "arraybuffer",
        success(){
          if (!chatItem.finish) {
            handleComplete()
          }
        }
    })
    requestTask.onChunkReceived((res: {data: ArrayBuffer}) => {
        if (chatItem.status === ChatStatusEnum.Stop) {
            requestTask.abort()
            return
        }
        try {
            const uint8Array = new Uint8Array(res.data);
            // 合并缓冲区
            const merged = new Uint8Array(buffer.length + uint8Array.length);
            merged.set(buffer);
            merged.set(uint8Array, buffer.length);
            // 尝试解码
            const decoder = new TextEncoding.TextDecoder("utf-8");
            let decoded = '';
            try {
                decoded = decoder.decode(merged, { stream: true });
                buffer = new Uint8Array(0); // 清空缓冲区
            } catch (e) {
                // 遇到不完整字符，保留最后3字节（最大UTF8字符长度）
                buffer = merged.slice(-3);
                decoded = decoder.decode(merged.slice(0, -3), { stream: false });
            }
            // console.log('decoded', decoded)
            const jsonStrArr = decoded.split('data: ').filter((jsonStr: string) => jsonStr !== '')
            jsonStrArr.forEach((jsonStr: string) => {
                try {
                    const jsonObj = JSON.parse(jsonStr)
                    if (Object.hasOwn(jsonObj, 'reasoning')) {
                        chatItem.loading = false
                        chatItem.status = ChatStatusEnum.Thinking
                        chatItem.reasoning += jsonObj.reasoning;
                        reasonCall && reasonCall(chatItem.reasoning)
                    }
                    if (Object.hasOwn(jsonObj, chatItem.answerKey)) {
                        chatItem.loading = false
                        chatItem.status = ChatStatusEnum.Loading
                        if (jsonObj[chatItem.answerKey] === '<|EOS|>') {
                            console.log('********* 对话结束标志 ***********')
                            handleComplete()
                        } else {
                            chatItem.aispire += jsonObj[chatItem.answerKey];
                            answerCall && answerCall(chatItem.aispire)
                        }
                    }
                    if (Object.hasOwn(jsonObj, 'error')) {
                        // 出错了
                        handleComplete()
                        chatItem.aispire = jsonObj['error']
                        errorCall && errorCall(chatItem.aispire)
                    }
                } catch(e){}
            })
        } catch (e) {
            console.error("数据处理异常:", e);
        }
    });
}
export default {
    post,
    get,
    stream,
}
